from odoo import api, models, fields, _
from odoo.exceptions import ValidationError


class SplitOrderWizard(models.TransientModel):
    _name = 'split.order.wizard'
    _description = '拆分订单'

    sale_order_id = fields.Many2one('sale.order', string='Sale Order',
                                    default=lambda self: self.env.context.get('sale_order_id', False))
    line_ids = fields.One2many('split.order.line.wizard', 'split_order_id')
    product_uom_qty = fields.Integer(string='Qty', help='原始订单的总数量',
                                     default=lambda self: self.env.context.get('qty', False))
    remain_qty = fields.Integer(string='Remain Qty', default=lambda self: self.env.context.get('qty', False),
                                help='当前销售订单剩余数量')
    pn = fields.Char(string='PN')
    pn_rev = fields.Char(string='PN REV')
    origin_date = fields.Datetime(related='sale_order_id.commitment_date', string='Commitment date')

    # commitment_date = fields.Datetime(string="交货日期", related='sale_order_id.commitment_date')
    # planned_receiving_date = fields.Datetime(related='sale_order_id.planned_receiving_date')

    @api.onchange('line_ids')
    def onchange_remain_qty(self):
        remain_qty = self.product_uom_qty
        for l in self.line_ids:
            remain_qty -= l.qty
            if remain_qty < 0:
                raise ValidationError('拆分订单数量最大不能超过{}'.format(self.product_uom_qty))
        self.remain_qty = remain_qty

    def action_split(self):
        # 取消，暂停，完成，都不能产生欠单
        # 存在发货单且发货的已交货或者部分交货，都不能拆单
        # 拆单后存在交货单的自动产生交货单
        order_line = self.sale_order_id.order_line[0]
        change_line_id = self._context.get('change_line_id', False)
        change_line = self.env['sb.sale.change.line'].search([('id', '=', change_line_id)])
        workflow_tmpl_id = self.env['sb.workflow.template'].search([('workflow_type', '=', 'sale')])[0]
        for l in self.line_ids:
            new_sale_id = self.create_sale_order(l, order_line, l.qty, workflow_tmpl_id)
            # 1 生成审批单据
            new_sale_id.create_workflow()
            # 2 审批单自动通过
            self.auto_approve(new_sale_id)
            # 3 审批通过后已经自动确认销售单，并生成交货单
            # new_sale_id.action_confirm()
        # 4 剩余的数量回写原始单据（防止原单据有服务类型的产品，所以选择copy)
        self.sale_order_id.order_line[0].product_uom_qty = self.remain_qty
        self.sale_order_id.order_line[0].price_unit = order_line.price_unit
        change_line.is_option = True
        change_line.change_id.is_option = True
        change_line.send_message_port('订单已经拆分{}'.format(change_line.sale_order_id.name))
        self._unlock_order()
        return {
            'name': _('Sale Order'),
            'type': 'ir.actions.act_window',
            'res_model': 'sale.order',
            'view_mode': 'tree,form',
            'target': 'current',
            'domain': ['|', ('origin_sale_order', '=', self.sale_order_id.name), ('name', '=', self.sale_order_id.name)]}

    def create_sale_order(self, l, order_line, qty, workflow_tmpl_id):
        name = self.env['ir.sequence'].next_by_code('sale.order')
        # 创建新的销售单
        new_sale_id = self.env['sale.order'].sudo().create({
            'partner_id': self.sale_order_id.partner_id.id,
            'special_order_type': self.sale_order_id.special_order_type,
            'po': self.sale_order_id.po,
            'commitment_date': l.commitment_date,
            'planned_receiving_date': l.planned_receiving_date,
            'name': name + '-001',
            'crm_id': self.sale_order_id.opportunity_id.id,
            'order_type': self.sale_order_id.order_type,
            'origin_sale_order': self.sale_order_id.name,
            'sb_workflow_template_id': workflow_tmpl_id.id,
            'order_line': [(0, 0, {
                'product_template_id': order_line.product_template_id.id,
                'product_id': order_line.product_id.id,
                'product_uom_qty': l.qty,
                'price_unit': order_line.price_unit,
                'origin_price': order_line.origin_price,
                'name': order_line.product_template_id.name,
                'product_uom': order_line.product_template_id.uom_id.id,
            })]
        })
        return new_sale_id

    def auto_approve(self, new_sale_id):
        # 自动审批通过，绕开审核限制
        for item in new_sale_id.sb_workflow_item_ids:
            item.sb_workflow_id_state = 'approve'
            item.state = 'pass'
        new_sale_id.sb_workflow_id.state = 'approve'

    def _unlock_order(self):
        # 解锁销售单、发货的、工单、报废、过数等
        # order_lines = set()
        # picking_ids = set()
        mrp_prods = set()
        # 解锁销售单
        self.sale_order_id.is_lock = False
        order_lines = self.sale_order_id.order_line
        picking_ids = self.sale_order_id.picking_ids
        self.sale_order_id.option_mrp_production_ids.filtered(lambda x: x.is_lock).is_lock = False
        for line in order_lines:
            for mrp in line.s_mrp_production_ids:
                if not mrp_prods:
                    mrp_prods = mrp
                mrp_prods |= self._get_parent_mrp(mrp)
                mrp_prods |= self._get_child_mrp(mrp)
                picking_ids |= mrp.picking_ids

        # 解锁工单
        for mrp in mrp_prods:
            mrp.filtered(lambda x: x.state != 'done').is_lock = False
            # mrp.is_lock = True
        # 解锁picking(出库和生产)
        for picking in picking_ids:
            picking.filtered(lambda x: x.state != 'done').is_lock = False
            # picking.is_lock = True

    def _get_parent_mrp(self, mrp):
        parent_ids = mrp._get_sources()
        # 欠单
        mrp_backorders = mrp.procurement_group_id.mrp_production_ids
        return parent_ids | mrp_backorders | mrp

    def _get_child_mrp(self, mrp):
        child_ids = mrp._get_children()
        # 欠单
        mrp_backorders = mrp.procurement_group_id.mrp_production_ids
        return child_ids | mrp_backorders


class SplitOrderLineWizard(models.TransientModel):
    _name = 'split.order.line.wizard'
    _description = '拆分订单'

    split_order_id = fields.Many2one('split.order.wizard')
    qty = fields.Integer(string='数量')
    mrp_qty = fields.Integer(string='在部件中')
    commitment_date = fields.Datetime(string="交货日期")
    planned_receiving_date = fields.Datetime(string='计划日期')
